home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / util / misc / 2b_CAF.lha / caf / src / caf.c
C/C++ Source or Header  |  1999-03-18  |  10KB  |  443 lines

  1. /*  CSAminet ver. 0.0.1 (13-Mar-99)
  2.     Copyright (C) 1999  Karol Bryd (kbryd@femina.com.pl)
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23.  
  24. #include <proto/dos.h>
  25. #include <proto/exec.h>
  26.  
  27. #include <dos/dos.h>
  28. #include <dos/dosextens.h>
  29. #include <exec/memory.h>
  30. #include <utility/tagitem.h>
  31.  
  32. #define BOLD      "\033[1m"
  33. #define NORMAL    "\033[0m"
  34.  
  35. static char *ver[]={"$VER: CAF 1.0 (13-03-99)"};
  36.  
  37. static char archives_path[32];
  38. static char tree_path[108];
  39. static char temp_path[108];
  40.  
  41. static char command[255];
  42.  
  43. int simulate = FALSE;
  44.  
  45. char *stristr(char *buf, char *str)
  46. {
  47.     register int len = strlen(buf);
  48.     register int len2 = strlen(str);
  49.     register int a;
  50.  
  51.     for(a = 0; a <= len - len2; a++)
  52.         if(strnicmp(&buf[a], str, len2) == 0)
  53.             return(&buf[a]);
  54.     return(0);
  55. }
  56.  
  57. int get_type(char *in, char *out, char *header)
  58. {
  59.     int n = 0, i = 0;
  60.     char *h;
  61.  
  62.     h = stristr(in, header);
  63.  
  64.     if(h)
  65.     {
  66.         while(h[n] != ':')
  67.             n++;
  68.  
  69.         n += 2;
  70.  
  71.         while(1)
  72.         {
  73.             while(h[n] != 10)
  74.                 out[i++] = h[n++];
  75.  
  76.             if(h[n - 1] != ',')
  77.                 break;
  78.             else
  79.             {
  80.                 while(isspace(h[n++])) ;
  81.                 n--;
  82.             }
  83.         }
  84.  
  85.         out[i] = 0;
  86.         return(TRUE);
  87.     }
  88.     return(FALSE);
  89. }
  90.  
  91. void check_for_dir(char *path_in)
  92. {
  93.     BPTR lock;
  94.  
  95.     lock = Lock(path_in, ACCESS_READ);
  96.     if(lock)
  97.     {
  98.         UnLock(lock);
  99.         return;
  100.     }
  101.  
  102.     sprintf(command, "makedir >nil: %s", path_in);
  103.     system(command);
  104. }
  105.  
  106. void copy_archive(char *src, char *dest, char *readme)
  107. {
  108.     check_for_dir(dest);
  109.  
  110.     sprintf(command, "c:copy >nil: %s %s", src, dest);
  111.     system(command);
  112.  
  113.     printf(BOLD "Moved %s to %s\n" NORMAL, src, dest);
  114.  
  115.     sprintf(command, "c:copy >nil: %s %s", readme, dest);
  116.     system(command);
  117.  
  118.     if(!simulate)
  119.     {
  120.         char *ln;
  121.  
  122.         sprintf(command, "c:delete >nil: %s QUIET", src);
  123.         system(command);
  124.  
  125.         ln = strchr(src, '.');
  126.         if(ln)
  127.             *ln = 0;
  128.  
  129.         sprintf(command, "c:delete >nil: %s.readme QUIET", src);
  130.         system(command);
  131.     }
  132. }
  133.  
  134. char *scan_for_readme(char *start_dir)
  135. {
  136.     char readme_path[255];
  137.     struct FileInfoBlock *fib;
  138.     BPTR lock;
  139.  
  140.     fib = AllocDosObject(DOS_FIB, TAG_DONE);
  141.     if(!fib)
  142.         return(NULL);
  143.  
  144.     lock = Lock(start_dir, ACCESS_READ);
  145.  
  146.     bzero(readme_path, sizeof(readme_path));
  147.     Examine(lock, fib);
  148.  
  149.     while(ExNext(lock, fib))
  150.     {
  151.         if(fib->fib_EntryType < -2)
  152.         {
  153.             if(astcsma(fib->fib_FileName, "#?.readme") != 0)
  154.             {
  155.                 static char filename[108];
  156.  
  157.                 strcpy(filename, start_dir);
  158.                 AddPart(filename, fib->fib_FileName, sizeof(filename));
  159.                 FreeDosObject(DOS_FIB, fib);
  160.                 UnLock(lock);
  161.                 return(filename);
  162.             }
  163.         }
  164.         else if(fib->fib_EntryType == ST_USERDIR)
  165.         {
  166.             char *ret;
  167.  
  168.             strcpy(readme_path, start_dir);
  169.             AddPart(readme_path, fib->fib_FileName, sizeof(readme_path));
  170.             if(ret = scan_for_readme(readme_path))
  171.             {
  172.                 FreeDosObject(DOS_FIB, fib);
  173.                 UnLock(lock);
  174.  
  175.                 return(ret);
  176.             }
  177.         }
  178.     }
  179.  
  180.     FreeDosObject(DOS_FIB, fib);
  181.     UnLock(lock);
  182.     return(NULL);
  183. }
  184.  
  185. void unlha_process(char *name, char *readme)
  186. {
  187.     static char dest_name[108];
  188.     char temp_dir[108], full_name[108];
  189.     char rnd_name[32], type[32];
  190.     char *buf, *readme_name;
  191.     long size, broken = FALSE, correct_archive = FALSE;
  192.     BPTR fh, lock, old_dir;
  193.  
  194.     strcpy(rnd_name, "CSA_XXXXXXXX");
  195.     mktemp(rnd_name);
  196.     strcpy(temp_dir, temp_path);
  197.     AddPart(temp_dir, rnd_name, 108);
  198.  
  199.     lock = Lock(temp_path, ACCESS_READ);
  200.     if(!lock)
  201.         return;
  202.  
  203.     old_dir = CurrentDir(lock);
  204.     UnLock(CreateDir(rnd_name));
  205.  
  206.     CurrentDir(old_dir);
  207.     UnLock(lock);
  208.  
  209.     strcpy(full_name, archives_path);
  210.     AddPart(full_name, name, 108);
  211.     sprintf(command, "lha >nil: -m -q x %s #?.readme %s/", full_name, temp_dir);
  212.     if(system(command) > 0)
  213.         broken = TRUE;
  214.  
  215.     readme_name = scan_for_readme(temp_dir);
  216.     if(readme_name)
  217.     {
  218.         fh = Open(readme_name, MODE_OLDFILE);
  219.         if(fh)
  220.         {
  221.             Seek(fh, 0, OFFSET_END);
  222.             size = Seek(fh, 0, OFFSET_BEGINNING);
  223.             buf = AllocVec(size, MEMF_ANY);
  224.             if(buf)
  225.             {
  226.                 Read(fh, buf, size);
  227.                 if(get_type(buf, type, "Type:"))
  228.                     correct_archive = TRUE;
  229.                 FreeVec(buf);
  230.             }
  231.             Close(fh);
  232.         }
  233.     }
  234.  
  235.     if(correct_archive)
  236.     {
  237.         if(broken)
  238.         {
  239.             strcpy(dest_name, tree_path);
  240.             AddPart(dest_name, "broken", sizeof(dest_name));
  241.             printf("Encountered damaged archive: \"%s\", moved to %s\n", name, dest_name);
  242.         }
  243.         else
  244.         {
  245.             strcpy(dest_name, tree_path);
  246.             AddPart(dest_name, stpblk(type), sizeof(dest_name));
  247.         }
  248.         copy_archive(name, dest_name, readme_name);
  249.     }
  250.     else
  251.         printf("Archive \"%s\" probably isn't from Aminet...Skipped.\n", name);
  252.  
  253.     sprintf(command, "c:delete >nil: %s ALL QUIET", temp_dir);
  254.     system(command);
  255. }
  256.  
  257. void process_file(char *name)
  258. {
  259.     static char dest_name[108];
  260.     static char local_name[108];
  261.     char *ext, *buf, type[32];
  262.     long size;
  263.     BPTR fh;
  264.  
  265.     strcpy(local_name, name);
  266.     ext = stristr(local_name, ".lha");
  267.     if(!ext)
  268.         return;
  269.  
  270.     *ext = 0;
  271.     strcat(ext, ".readme");
  272.     fh = Open(local_name, MODE_OLDFILE);
  273.     if(!fh)
  274.     {
  275.         unlha_process(name, local_name);
  276.         return;
  277.     }
  278.  
  279.     Seek(fh, 0, OFFSET_END);
  280.     size = Seek(fh, 0, OFFSET_BEGINNING);
  281.     buf = AllocVec(size, MEMF_ANY);
  282.     if(!buf)
  283.     {
  284.         Close(fh);
  285.         return;
  286.     }
  287.  
  288.     Read(fh, buf, size);
  289.     Close(fh);
  290.  
  291.     if(!(get_type(buf, type, "Type:")))
  292.         return;
  293.  
  294.     FreeVec(buf);
  295.     strcpy(dest_name, tree_path);
  296.     AddPart(dest_name, stpblk(type), sizeof(dest_name));
  297.  
  298.     copy_archive(name, dest_name, local_name);
  299. }
  300.  
  301. int scan_dir(void)
  302. {
  303.     struct FileInfoBlock *fib;
  304.     BPTR lock, fh;
  305.  
  306.     lock = Lock(archives_path, ACCESS_READ);
  307.     if(!lock)
  308.         return(-1);
  309.  
  310.     fib = AllocDosObject(DOS_FIB, TAG_DONE);
  311.  
  312.     Examine(lock, fib);
  313.  
  314.     while(ExNext(lock, fib))
  315.     {
  316.         if(fib->fib_EntryType < -2)
  317.         {
  318.             if(astcsma(fib->fib_FileName, "#?.lha") != 0)
  319.                 process_file(fib->fib_FileName);
  320.         }
  321.     }
  322.  
  323.     UnLock(lock);
  324.     FreeDosObject(DOS_FIB, fib);
  325. }
  326.  
  327. void create_tree(void)
  328. {
  329.     BPTR lock, fh, old_dir, initial_dir = 0;
  330.     char buf[32];
  331.     char path[108];
  332.  
  333.     fh = Open("tree", MODE_OLDFILE);
  334.     if(!fh)
  335.     {
  336.         printf("No \"tree\" file in current directory!\n");
  337.         return;
  338.     }
  339.     bzero(path, sizeof(path));
  340.  
  341.     lock = Lock(tree_path, ACCESS_READ);
  342.     old_dir = CurrentDir(lock);
  343.  
  344.     while(FGets(fh, buf, sizeof(buf)))
  345.     {
  346.         char *white;
  347.         BPTR new_dir_lock;
  348.  
  349.         white = strchr(buf, ' ');
  350.         if(white)
  351.             *white = 0;
  352.  
  353.         strcpy(path, tree_path);
  354.         AddPart(path, buf, 108);
  355.  
  356.         new_dir_lock = CreateDir(buf);
  357.         if(new_dir_lock)
  358.             UnLock(new_dir_lock);
  359.  
  360.         // create subdirectory trees
  361.  
  362.         {
  363.             BPTR sub_old_dir, sub_lock;
  364.             BPTR su